from fastapi import APIRouter, HTTPException
from pydantic import BaseModel, HttpUrl, validator
from typing import Optional
import logging

from service.youtube_downloader_service import YouTubeDownloaderService
from utils.hls_downloader import HLSDownloader

logger = logging.getLogger(__name__)

router = APIRouter(prefix="/hls", tags=["HLS视频下载"])

class HLSDownloadRequest(BaseModel):
    """HLS下载请求模型"""
    hls_url: HttpUrl
    output_filename: Optional[str] = None
    
    @validator('hls_url')
    def validate_hls_url(cls, v):
        """验证HLS URL格式"""
        url_str = str(v)
        if not HLSDownloader.is_hls_url(url_str):
            raise ValueError('不是有效的HLS/M3U8链接')
        return v

class HLSDownloadResponse(BaseModel):
    """HLS下载响应模型"""
    success: bool
    data: Optional[dict] = None
    error: Optional[str] = None
    message: Optional[str] = None

@router.post("/download", response_model=HLSDownloadResponse)
async def download_hls_video(request: HLSDownloadRequest):
    """
    下载HLS视频并合成为完整视频文件
    
    这个接口可以处理M3U8播放列表格式的视频链接，
    自动下载所有视频片段并合成为完整的MP4视频文件。
    
    Args:
        request: HLS下载请求，包含M3U8链接和可选的输出文件名
        
    Returns:
        下载结果，包含文件路径、大小等信息
        
    Examples:
        ```bash
        curl -X POST "http://localhost:8000/hls/download" \
             -H "Content-Type: application/json" \
             -d '{
               "hls_url": "https://manifest.googlevideo.com/api/manifest/hls_playlist/...",
               "output_filename": "my_video.mp4"
             }'
        ```
    """
    try:
        logger.info(f"收到HLS下载请求: {request.hls_url}")
        
        # 使用YouTube下载服务的HLS功能
        youtube_service = YouTubeDownloaderService()
        
        result = await youtube_service.download_hls_video(
            str(request.hls_url),
            request.output_filename
        )
        
        if result["success"]:
            return HLSDownloadResponse(
                success=True,
                data={
                    "output_path": result["output_path"],
                    "file_size": result["file_size"],
                    "file_size_mb": round(result["file_size"] / (1024 * 1024), 2),
                    "segments_total": result["segments_total"],
                    "segments_downloaded": result["segments_downloaded"],
                    "download_rate": result["download_rate"],
                    "download_completed": result["segments_downloaded"] == result["segments_total"]
                },
                message=result.get("message", "HLS视频下载并合成成功")
            )
        else:
            return HLSDownloadResponse(
                success=False,
                error=result["error"]
            )
            
    except ValueError as e:
        logger.error(f"HLS下载请求参数错误: {str(e)}")
        raise HTTPException(status_code=400, detail=str(e))
        
    except Exception as e:
        logger.error(f"HLS下载过程发生错误: {str(e)}")
        raise HTTPException(status_code=500, detail=f"内部服务器错误: {str(e)}")

@router.post("/diagnose", response_model=dict)
async def diagnose_hls_url(request: dict):
    """
    诊断HLS链接的详细信息和可访问性
    
    Args:
        request: 包含hls_url字段的请求
        
    Returns:
        详细的诊断结果
        
    Examples:
        ```bash
        curl -X POST "http://localhost:8000/hls/diagnose" \
             -H "Content-Type: application/json" \
             -d '{"hls_url": "https://manifest.googlevideo.com/api/manifest/hls_playlist/..."}'
        ```
    """
    try:
        hls_url = request.get("hls_url")
        if not hls_url:
            raise HTTPException(status_code=400, detail="缺少hls_url参数")
            
        logger.info(f"收到HLS诊断请求: {hls_url[:100]}...")
        
        # 使用HLS下载器进行诊断
        async with HLSDownloader() as downloader:
            diagnosis = await downloader.diagnose_hls_url(hls_url)
            
        if diagnosis["success"]:
            return {
                "success": True,
                "data": diagnosis
            }
        else:
            return {
                "success": False,
                "error": diagnosis["error"]
            }
            
    except Exception as e:
        logger.error(f"HLS链接诊断失败: {str(e)}")
        raise HTTPException(status_code=500, detail=f"诊断过程发生错误: {str(e)}")

@router.post("/validate", response_model=dict)
async def validate_hls_url(request: dict):
    """
    验证HLS链接是否有效
    
    Args:
        request: 包含hls_url字段的请求
        
    Returns:
        验证结果
        
    Examples:
        ```bash
        curl -X POST "http://localhost:8000/hls/validate" \
             -H "Content-Type: application/json" \
             -d '{"hls_url": "https://manifest.googlevideo.com/api/manifest/hls_playlist/..."}'
        ```
    """
    try:
        hls_url = request.get("hls_url")
        if not hls_url:
            raise HTTPException(status_code=400, detail="缺少hls_url参数")
            
        is_valid = HLSDownloader.is_hls_url(hls_url)
        
        return {
            "success": True,
            "data": {
                "hls_url": hls_url,
                "is_valid": is_valid,
                "url_type": "HLS/M3U8" if is_valid else "Unknown",
                "message": "有效的HLS链接" if is_valid else "不是HLS链接格式"
            }
        }
        
    except Exception as e:
        logger.error(f"HLS链接验证失败: {str(e)}")
        raise HTTPException(status_code=500, detail=f"验证过程发生错误: {str(e)}")

@router.get("/info", response_model=dict)
async def get_hls_info():
    """
    获取HLS下载器信息和使用说明
    
    Returns:
        HLS下载器的功能介绍和使用说明
    """
    return {
        "success": True,
        "data": {
            "name": "HLS视频下载器",
            "description": "用于下载和合成HLS/M3U8格式的流媒体视频",
            "features": [
                "支持M3U8播放列表解析",
                "并发下载视频片段",
                "自动合成完整视频文件",
                "支持FFmpeg和直接合并两种模式",
                "自动清理临时文件"
            ],
            "supported_formats": [
                "M3U8播放列表",
                "HLS流媒体",
                "TS视频片段"
            ],
            "output_format": "MP4",
            "requirements": {
                "optional": ["FFmpeg (推荐，用于更好的视频质量)"],
                "required": ["aiohttp", "asyncio"]
            },
            "usage_example": {
                "endpoint": "/hls/download",
                "method": "POST",
                "request_body": {
                    "hls_url": "https://manifest.googlevideo.com/api/manifest/hls_playlist/...",
                    "output_filename": "video.mp4"
                }
            }
        }
    } 